package com.ruoyi.ucar.util;



import cn.hutool.core.lang.UUID;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.ucar.common.CommonVoResp;
import com.ruoyi.ucar.common.ResultEnum;
import org.apache.commons.io.IOUtils;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.security.MessageDigest;
import java.util.regex.Pattern;

public class CommonUtil {


    /**
     * 设置VO层响应结果——文件不合法
     * @param commonVoResp
     * @return
     */
    public static CommonVoResp setCommonVoRespErrorFile(CommonVoResp commonVoResp){
        commonVoResp.setCode(ResultEnum.FILEERROR.getCode());
        commonVoResp.setMessage(ResultEnum.FILEERROR.getMsg());
        return commonVoResp;
    }


    /**
     * 设置vo层响应bean参数缺失
     * @param commonVoResp
     * @return
     */
    public static CommonVoResp setCommonVoRespNoParam(CommonVoResp commonVoResp){
        commonVoResp.setCode(ResultEnum.NOPARAM.getCode());
        commonVoResp.setMessage(ResultEnum.NOPARAM.getMsg());
        return commonVoResp;
    }
    public static CommonVoResp setCommonVoRespNoSignParam(CommonVoResp commonVoResp){
        commonVoResp.setCode(ResultEnum.SIGNNOPARAM.getCode());
        commonVoResp.setMessage(ResultEnum.SIGNNOPARAM.getMsg());
        return commonVoResp;
    }


    public static CommonVoResp setCommonVoRespWxPayError(CommonVoResp commonVoResp){
        commonVoResp.setCode(ResultEnum.PAYERROR.getCode());
        commonVoResp.setMessage(ResultEnum.PAYERROR.getMsg());
        return commonVoResp;
    }

    public static CommonVoResp setCommonVoRespCarQueryNoPayError(CommonVoResp commonVoResp){
        commonVoResp.setCode(ResultEnum.UCARQUERYNOPAYERROR.getCode());
        commonVoResp.setMessage(ResultEnum.UCARQUERYNOPAYERROR.getMsg());
        return commonVoResp;
    }

    public static CommonVoResp setCommonVoRespCarCommitNoPayError(CommonVoResp commonVoResp){
        commonVoResp.setCode(ResultEnum.UCARCOMMITNOPAYERROR.getCode());
        commonVoResp.setMessage(ResultEnum.UCARCOMMITNOPAYERROR.getMsg());
        return commonVoResp;
    }

    public static CommonVoResp setCommonVoRespNoDataError(CommonVoResp commonVoResp){
        commonVoResp.setCode(ResultEnum.NODATAERROR.getCode());
        commonVoResp.setMessage(ResultEnum.NODATAERROR.getMsg());
        return commonVoResp;
    }


    /**
     * 类型转换工具   VO转BO ，BO转PO  相同属性可转 ，不同属性手动set
     * @param source
     * @param targetClazz
     * @param <T>
     * @return
     */
    public static <T>T objToObj(Object source, Class<T> targetClazz) {
        try {
            T target = targetClazz.newInstance();
            Class sourceClazz = source.getClass();

            Field[] sourceFields = sourceClazz.getDeclaredFields();
            Field[] targetFields = target.getClass().getDeclaredFields();

            for (Field sourceField : sourceFields) {
                sourceField.setAccessible(true);
                for (Field targetField : targetFields) {
                    if (targetField.getName().equals(sourceField.getName()) && targetField.getType() == sourceField.getType()) {
                        int mod = targetField.getModifiers();
                        if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                            continue;
                        }
                        targetField.setAccessible(true);
                        targetField.set(target, sourceField.get(source));
                        break;
                    }
                }
            }
            return target;
        }catch (Exception e){
            return null;
        }
    }
    public static String lemonGenerateSign(String appKey, String vin,
                                      String timestamp, String appSecret) {
        try {
            // 1. 拼接签名字符串
            String rawString = String.format("appkey=%s&vin=%s&timestamp=%s%s",
                    appKey, vin, timestamp, appSecret);

            // 2. 生成MD5签名
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hash = md.digest(rawString.getBytes("UTF-8"));

            // 3. 转换为16进制字符串
            Formatter formatter = new Formatter();
            for (byte b : hash) {
                formatter.format("%02x", b);
            }
            return formatter.toString();
        } catch (Exception e) {
            throw new RuntimeException("生成签名失败", e);
        }
    }
    public static String lemonGenerateSign2(String appKey,
                                           String timestamp, String appSecret) {
        try {
            // 1. 按格式拼接原始字符串
            String rawString = String.format("appkey=%s&timestamp=%s%s",
                    appKey, timestamp, appSecret);

            // 2. 创建MD5实例
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(rawString.getBytes("UTF-8"));

            // 3. 生成16进制签名
            Formatter formatter = new Formatter();
            for (byte b : md.digest()) {
                formatter.format("%02x", b);
            }
            return formatter.toString();
        } catch (Exception e) {
            throw new RuntimeException("生成签名失败", e);
        }
    }

    public static String cheXinMengCreateSign(String timestamp,String cheXinMengAppKey,String cheXinMengAppSecret )
    {
        Map<String, String> parameters = new HashMap<String, String>();
        parameters.put("app_key", cheXinMengAppKey);
        parameters.put("timestamp", timestamp);
        return cheXinMengCetSignString(parameters, cheXinMengAppSecret);
    }




    /**
     * 生成签名字符串
     */
    private static String cheXinMengCetSignString(Map<String, String> parameters, String appSecret) {
        Map<String, String> sortedParams = new TreeMap<>(parameters);
        StringBuilder query = new StringBuilder(appSecret);

        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (key != null && !key.isEmpty()) {
                query.append(key).append(value);
            }
        }

        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(query.toString().getBytes("UTF-8"));
            StringBuilder result = new StringBuilder();
            for (byte b : bytes) {
                result.append(String.format("%02X", b));
            }
            return result.toString();
        } catch (Exception e) {
            throw new RuntimeException("MD5加密失败", e);
        }
    }
    public static String convertBase64FromUrl(String imageUrl) throws Exception {
        byte[] imageData = IOUtils.toByteArray(new URL(imageUrl).openStream());
        return Base64.getEncoder().encodeToString(imageData);
    }

    public static String convertBase64FromFile(File file) throws Exception {
        try(FileInputStream fis = new FileInputStream(file)){
            byte[] bytes = new byte[(int)file.length()];
            fis.read(bytes);
            return Base64.getEncoder().encodeToString(bytes);
        }
    }
    public static String convertBase64FromImagePath(String imagePath) throws Exception {
        byte[] fileContent = Files.readAllBytes(Paths.get(imagePath));
        return Base64.getEncoder().encodeToString(fileContent);
    }

    private static final int BUFFER_SIZE = 4096;

    public static String convertBase64FromInput(InputStream is)  {
        try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                output.write(buffer, 0, bytesRead);
            }
            return Base64.getEncoder().encodeToString(output.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 生成缩略图
     * @param base64Data 不带头的Base64图片数据
     * @param format 输出格式(jpg/png等)
     * @param maxWidth 最大宽度
     * @param maxHeight 最大高度
     * @param quality 压缩质量(0-1)
     * @return 缩略图Base64字符串
     */
    public static String createThumbnail(String base64Data, String format,
                                         int maxWidth, int maxHeight, float quality) throws Exception {
        // Base64解码
        byte[] imageBytes = Base64.getDecoder().decode(base64Data);
        BufferedImage srcImage = ImageIO.read(new ByteArrayInputStream(imageBytes));

        // 计算等比例尺寸
        int[] dimensions = calculateDimensions(srcImage.getWidth(), srcImage.getHeight(), maxWidth, maxHeight);

        // 创建缩略图
        BufferedImage thumbnail = new BufferedImage(dimensions[0], dimensions[1], BufferedImage.TYPE_INT_RGB);
        Graphics2D g = thumbnail.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(srcImage, 0, 0, dimensions[0], dimensions[1], null);
        g.dispose();

        // 编码输出
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        if ("jpg".equalsIgnoreCase(format) || "jpeg".equalsIgnoreCase(format)) {
            writeWithQuality(thumbnail, "JPEG", baos, quality);
        } else {
            ImageIO.write(thumbnail, format, baos);
        }
        return Base64.getEncoder().encodeToString(baos.toByteArray());
    }
    private static void writeWithQuality(BufferedImage image, String format,
                                         ByteArrayOutputStream output, float quality) throws Exception {
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(format);
        ImageWriter writer = writers.next();
        ImageWriteParam param = writer.getDefaultWriteParam();
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(quality);
        writer.setOutput(ImageIO.createImageOutputStream(output));
        writer.write(null, new IIOImage(image, null, null), param);
        writer.dispose();
    }
    private static int[] calculateDimensions(int origWidth, int origHeight, int maxW, int maxH) {
        double ratio = Math.min((double)maxW / origWidth, (double)maxH / origHeight);
        return new int[]{(int)(origWidth * ratio), (int)(origHeight * ratio)};
    }

    public static String createUuid(){
        return UUID.randomUUID().toString();
    }
    private static final String PHONE_REGEX = "^1[2-9]\\d{9}$";

    public static boolean isMobilePhoneValid(String phone) {
        if (StringUtils.isEmpty(phone)) {
            return false;
        }
        return Pattern.compile(PHONE_REGEX).matcher(phone).matches();
    }
    public static void main(String[] args) {
        System.out.println(createUuid());
    }
}
